package com.acme.domain.account;

import com.acme.exceptions.AccountClosedException;
import com.acme.exceptions.NotEnoughFundsException;

@SuppressWarnings("serial")
public class SavingAccount extends AbstractAccount {

	public SavingAccount(double amount) {
		super(amount);
		this.accountType = AccountType.SAVING;
		this.accountInfo.append("Account initial amount " + amount + "\n");
	}

	@Override
	public void withdraw(double amount) throws NotEnoughFundsException, AccountClosedException {
		if(this.accountState.equals(AccountState.OPENED)) {
			if(amount >= 0) {
				if(this.balance >= amount) {
					this.balance -= amount;
					this.accountInfo.append("Withdrawed: " + amount + "\n");
				} else {
					throw new NotEnoughFundsException("Not enough funds!");
				}
			} else {
				throw new IllegalArgumentException("amount should be non-negative!");
			}
		} else {
			throw new AccountClosedException("account is closed");
		}
	}

	@Override
	public double maximumAmountToWithdraw() {
		return this.balance;
	}

	public AccountType getAccountType() {
		return accountType;
	}

	@Override
	public boolean equals(Object obj) {
		if(this == obj) return true;
		if(obj == null) return false;
		SavingAccount other = (SavingAccount)obj;
		if(this.balance != other.balance) return false;
		if(this.id != other.id) return false;
		if(this.accountInfo.toString().equals(other.accountInfo.toString())) return false;
		return true;
	}

	@Override
	public int hashCode() {
		int hash = 37;
		hash = hash + 23 * this.accountInfo.hashCode();
		hash = hash + 17 * (int)this.balance;
		hash = hash + 29 * this.id;
		hash = Math.abs(hash % 89);
		return hash;
	}

	@Override
	public int toDecimalValue() {
		return (int)Math.round(this.maximumAmountToWithdraw());
	}

	@Override
	public AccountState getAccountState() {
		return accountState;
	}
	
}
